home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / os2 / e33el2.zip / emacs / 19.33 / lisp / prolog.el < prev    next >
Lisp/Scheme  |  1996-01-20  |  9KB  |  274 lines

  1. ;;; prolog.el --- major mode for editing and running Prolog under Emacs
  2.  
  3. ;; Copyright (C) 1986, 1987 Free Software Foundation, Inc.
  4.  
  5. ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
  6. ;; Keywords: languages
  7.  
  8. ;; This file is part of GNU Emacs.
  9.  
  10. ;; GNU Emacs is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14.  
  15. ;; GNU Emacs is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. ;; GNU General Public License for more details.
  19.  
  20. ;; You should have received a copy of the GNU General Public License
  21. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  22. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  23. ;; Boston, MA 02111-1307, USA.
  24.  
  25. ;;; Commentary:
  26.  
  27. ;; This package provides a major mode for editing Prolog.  It knows
  28. ;; about Prolog syntax and comments, and can send regions to an inferior
  29. ;; Prolog interpreter process.
  30.  
  31. ;;; Code:
  32.  
  33. (defvar prolog-mode-syntax-table nil)
  34. (defvar prolog-mode-abbrev-table nil)
  35. (defvar prolog-mode-map nil)
  36.   
  37. (defvar prolog-program-name "prolog"
  38.   "*Program name for invoking an inferior Prolog with `run-prolog'.")
  39.  
  40. (defvar prolog-consult-string "reconsult(user).\n"
  41.   "*(Re)Consult mode (for C-Prolog and Quintus Prolog). ")
  42.  
  43. (defvar prolog-compile-string "compile(user).\n"
  44.   "*Compile mode (for Quintus Prolog).")
  45.  
  46. (defvar prolog-eof-string "end_of_file.\n"
  47.   "*String that represents end of file for prolog.
  48. nil means send actual operating system end of file.")
  49.  
  50. (defvar prolog-indent-width 4)
  51.  
  52. (if prolog-mode-syntax-table
  53.     ()
  54.   (let ((table (make-syntax-table)))
  55.     (modify-syntax-entry ?_ "w" table)
  56.     (modify-syntax-entry ?\\ "\\" table)
  57.     (modify-syntax-entry ?/ "." table)
  58.     (modify-syntax-entry ?* "." table)
  59.     (modify-syntax-entry ?+ "." table)
  60.     (modify-syntax-entry ?- "." table)
  61.     (modify-syntax-entry ?= "." table)
  62.     (modify-syntax-entry ?% "<" table)
  63.     (modify-syntax-entry ?\n ">" table)
  64.     (modify-syntax-entry ?< "." table)
  65.     (modify-syntax-entry ?> "." table)
  66.     (modify-syntax-entry ?\' "\"" table)
  67.     (setq prolog-mode-syntax-table table)))
  68.  
  69. (define-abbrev-table 'prolog-mode-abbrev-table ())
  70.  
  71. (defun prolog-mode-variables ()
  72.   (set-syntax-table prolog-mode-syntax-table)
  73.   (setq local-abbrev-table prolog-mode-abbrev-table)
  74.   (make-local-variable 'paragraph-start)
  75.   (setq paragraph-start (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
  76.   (make-local-variable 'paragraph-separate)
  77.   (setq paragraph-separate paragraph-start)
  78.   (make-local-variable 'paragraph-ignore-fill-prefix)
  79.   (setq paragraph-ignore-fill-prefix t)
  80.   (make-local-variable 'indent-line-function)
  81.   (setq indent-line-function 'prolog-indent-line)
  82.   (make-local-variable 'comment-start)
  83.   (setq comment-start "%")
  84.   (make-local-variable 'comment-start-skip)
  85.   (setq comment-start-skip "%+ *")
  86.   (make-local-variable 'comment-column)
  87.   (setq comment-column 48)
  88.   (make-local-variable 'comment-indent-function)
  89.   (setq comment-indent-function 'prolog-comment-indent))
  90.  
  91. (defun prolog-mode-commands (map)
  92.   (define-key map "\t" 'prolog-indent-line)
  93.   (define-key map "\e\C-x" 'prolog-consult-region))
  94.  
  95. (if prolog-mode-map
  96.     nil
  97.   (setq prolog-mode-map (make-sparse-keymap))
  98.   (prolog-mode-commands prolog-mode-map))
  99.  
  100. ;;;###autoload
  101. (defun prolog-mode ()
  102.   "Major mode for editing Prolog code for Prologs.
  103. Blank lines and `%%...' separate paragraphs.  `%'s start comments.
  104. Commands:
  105. \\{prolog-mode-map}
  106. Entry to this mode calls the value of `prolog-mode-hook'
  107. if that value is non-nil."
  108.   (interactive)
  109.   (kill-all-local-variables)
  110.   (use-local-map prolog-mode-map)
  111.   (setq major-mode 'prolog-mode)
  112.   (setq mode-name "Prolog")
  113.   (prolog-mode-variables)
  114.   (run-hooks 'prolog-mode-hook))
  115.  
  116. (defun prolog-indent-line (&optional whole-exp)
  117.   "Indent current line as Prolog code.
  118. With argument, indent any additional lines of the same clause
  119. rigidly along with this one (not yet)."
  120.   (interactive "p")
  121.   (let ((indent (prolog-indent-level))
  122.     (pos (- (point-max) (point))) beg)
  123.     (beginning-of-line)
  124.     (setq beg (point))
  125.     (skip-chars-forward " \t")
  126.     (if (zerop (- indent (current-column)))
  127.     nil
  128.       (delete-region beg (point))
  129.       (indent-to indent))
  130.     (if (> (- (point-max) pos) (point))
  131.     (goto-char (- (point-max) pos)))
  132.     ))
  133.  
  134. (defun prolog-indent-level ()
  135.   "Compute prolog indentation level."
  136.   (save-excursion
  137.     (beginning-of-line)
  138.     (skip-chars-forward " \t")
  139.     (cond
  140.      ((looking-at "%%%") 0)        ;Large comment starts
  141.      ((looking-at "%[^%]") comment-column) ;Small comment starts
  142.      ((bobp) 0)                ;Beginning of buffer
  143.      (t
  144.       (let ((empty t) ind more less)
  145.     (if (looking-at ")")
  146.         (setq less t)        ;Find close
  147.       (setq less nil))
  148.     ;; See previous indentation
  149.     (while empty
  150.       (forward-line -1)
  151.       (beginning-of-line)
  152.        (if (bobp)
  153.            (setq empty nil)
  154.          (skip-chars-forward " \t")
  155.          (if (not (or (looking-at "%[^%]") (looking-at "\n")))
  156.          (setq empty nil))))
  157.      (if (bobp)
  158.          (setq ind 0)        ;Beginning of buffer
  159.       (setq ind (current-column)))    ;Beginning of clause
  160.     ;; See its beginning
  161.     (if (looking-at "%%[^%]")
  162.         ind
  163.       ;; Real prolog code
  164.       (if (looking-at "(")
  165.           (setq more t)        ;Find open
  166.         (setq more nil))
  167.       ;; See its tail
  168.       (end-of-prolog-clause)
  169.       (or (bobp) (forward-char -1))
  170.       (cond ((looking-at "[,(;>]")
  171.          (if (and more (looking-at "[^,]"))
  172.              (+ ind prolog-indent-width) ;More indentation
  173.            (max tab-width ind))) ;Same indentation
  174.         ((looking-at "-") tab-width) ;TAB
  175.         ((or less (looking-at "[^.]"))
  176.          (max (- ind prolog-indent-width) 0)) ;Less indentation
  177.         (t 0))            ;No indentation
  178.       )))
  179.      )))
  180.  
  181. (defun end-of-prolog-clause ()
  182.   "Go to end of clause in this line."
  183.   (beginning-of-line 1)
  184.   (let* ((eolpos (save-excursion (end-of-line) (point))))
  185.     (if (re-search-forward comment-start-skip eolpos 'move)
  186.     (goto-char (match-beginning 0)))
  187.     (skip-chars-backward " \t")))
  188.  
  189. (defun prolog-comment-indent ()
  190.   "Compute prolog comment indentation."
  191.   (cond ((looking-at "%%%") 0)
  192.     ((looking-at "%%") (prolog-indent-level))
  193.     (t
  194.      (save-excursion
  195.            (skip-chars-backward " \t")
  196.            ;; Insert one space at least, except at left margin.
  197.            (max (+ (current-column) (if (bolp) 0 1))
  198.             comment-column)))
  199.     ))
  200.  
  201.  
  202. ;;;
  203. ;;; Inferior prolog mode
  204. ;;;
  205. (defvar inferior-prolog-mode-map nil)
  206.  
  207. (defun inferior-prolog-mode ()
  208.   "Major mode for interacting with an inferior Prolog process.
  209.  
  210. The following commands are available:
  211. \\{inferior-prolog-mode-map}
  212.  
  213. Entry to this mode calls the value of `prolog-mode-hook' with no arguments,
  214. if that value is non-nil.  Likewise with the value of `comint-mode-hook'.
  215. `prolog-mode-hook' is called after `comint-mode-hook'.
  216.  
  217. You can send text to the inferior Prolog from other buffers
  218. using the commands `send-region', `send-string' and \\[prolog-consult-region].
  219.  
  220. Commands:
  221. Tab indents for Prolog; with argument, shifts rest
  222.  of expression rigidly with the current line.
  223. Paragraphs are separated only by blank lines and '%%'.
  224. '%'s start comments.
  225.  
  226. Return at end of buffer sends line as input.
  227. Return not at end copies rest of line to end and sends it.
  228. \\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
  229. \\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
  230. \\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal."
  231.   (interactive)
  232.   (require 'comint)
  233.   (comint-mode)
  234.   (setq major-mode 'inferior-prolog-mode
  235.     mode-name "Inferior Prolog"
  236.     comint-prompt-regexp "^| [ ?][- ] *")
  237.   (prolog-mode-variables)
  238.   (if inferior-prolog-mode-map nil
  239.     (setq inferior-prolog-mode-map (copy-keymap comint-mode-map))
  240.     (prolog-mode-commands inferior-prolog-mo